
/**
 *  \file device_queue_internal.h
 *
 *  Module Internal Header File for Device Queue module.
 */

/*
 *  Copyright (C) 2013. Mindtree Ltd.
 *  All rights reserved.
 */

#ifndef _H_DEVICE_QUEUE_INTERNAL_
#define _H_DEVICE_QUEUE_INTERNAL_

/* ----------------------------------------------- Header File Inclusion */
#include "BT_common.h"
#include "BT_hci_api.h"
#include "BT_device_queue.h"
#include "BT_security.h"

/* ----------------------------------------------- Device Queue Debug */

#ifndef DQ_NO_DEBUG
#define DQ_ERR(...)               BT_debug_error(BT_MODULE_ID_DQ,__VA_ARGS__)
#else  /* DQ_NO_DEBUG */
#ifdef VAR_ARG_IN_MACRO_NOT_SUPPORTED
#define DQ_ERR
#else
#define DQ_ERR(...)               BT_debug_null(BT_MODULE_ID_DQ,__VA_ARGS__)
#endif  /*  VAR_ARG_IN_MACRO_NOT_SUPPORTED */
#endif /* DQ_NO_DEBUG */

#ifdef DQ_DEBUG

#define DQ_TRC(...)               BT_debug_trace(BT_MODULE_ID_DQ,__VA_ARGS__)
#define DQ_INF(...)               BT_debug_info(BT_MODULE_ID_DQ,__VA_ARGS__)

#else /* DQ_DEBUG */

#ifdef VAR_ARG_IN_MACRO_NOT_SUPPORTED
#define DQ_TRC
#define DQ_INF
#else
#define DQ_TRC(...)               BT_debug_null(BT_MODULE_ID_DQ,__VA_ARGS__)
#define DQ_INF(...)               BT_debug_null(BT_MODULE_ID_DQ,__VA_ARGS__)
#endif  /*  VAR_ARG_IN_MACRO_NOT_SUPPORTED */

#endif /* DQ_DEBUG */

/**
 *  Locks the GENERIC_MANAGER Mutex which prevents any global variable being
 *  overwritten by any function. It returns an error if mutex lock fails.
 */
#define DQ_LOCK()\
    BT_MUTEX_LOCK(device_queue_mutex, DQ)

/**
 *  Locks the DQ_mutex which prevents any global variable being
 *  overwritten by any function. To be used in void function as it
 *  returns no error.
 */
#define DQ_LOCK_VOID()\
        BT_MUTEX_LOCK_VOID(device_queue_mutex, DQ)

/**
 *  Unlocks the DQ_mutex which realeses the global variables
 *  to be written into. It returns an error if mutex unlock fails.
 */
#define DQ_UNLOCK()\
    BT_MUTEX_UNLOCK(device_queue_mutex, DQ)

/**
 *  Unlocks the DQ_mutex which realeses the global variables
 *  to be written into. To be used in void functions as it returns
 *  no error.
 */
#define DQ_UNLOCK_VOID()\
        BT_MUTEX_UNLOCK_VOID(device_queue_mutex, DQ)

#ifdef DQ_NO_NULL_PARAM_CHECK
#define DQ_NULL_CHECK(x)
#else /* DQ_NO_NULL_PARAM_CHECK */
#define DQ_NULL_CHECK(x)\
        if (NULL == (x))\
        {\
            DQ_ERR(\
            "[DQ]: NULL Parameter Unacceptable\n");\
            return DQ_NULL_PARAMETER_NOT_ALLOWED;\
        }
#endif /* DQ_NO_NULL_PARAM_CHECK */

#define DQ_VALIDATE_HANDLE(x)\
        if (BT_MAX_DEVICE_QUEUE_SIZE <= (*(x)))\
        {\
            DQ_ERR(\
            "[DQ]: Invalid Device Handle 0x%02X\n",(*(x)));\
            return DQ_INVALID_HANDLE;\
        }

#define DQ_REMOTE_ADDR(h)\
        (&device_queue[(h)].remote_bd_addr)

#define DQ_LOCAL_ADDR(h)\
        (&device_queue[(h)].local_bd_addr)

#define DQ_LINK_TYPE(h)\
        device_queue[(h)].link_type

#define DQ_INIT_REMOTE_ADDR(h)\
        BT_INIT_BD_ADDR(DQ_REMOTE_ADDR(h))

#define DQ_INIT_LOCAL_ADDR(h)\
        BT_INIT_BD_ADDR(DQ_LOCAL_ADDR(h))

#define DEVICE_QUEUE_COMPARE_LINK_TYPE(i,l_t)\
        (DQ_LINK_TYPE((i)) == (l_t))? BT_TRUE : BT_FALSE

#ifdef BT_DUAL_MODE
#define DQ_INIT_ELEMENT(dqe) \
        BT_INIT_BD_ADDR(&((dqe).remote_bd_addr));\
        BT_INIT_BD_ADDR(&((dqe).local_bd_addr));\
        (dqe).link_type = DQ_LINK_NONE
#else
#define DQ_INIT_ELEMENT(dqe) \
        BT_INIT_BD_ADDR(&((dqe).remote_bd_addr));\
        BT_INIT_BD_ADDR(&((dqe).local_bd_addr))
#endif /* BT_DUAL_MODE */


/* ----------------------------------------------- Global Definitions */

/* ----------------------------------------------- Structures/Data Types */

/**
 * Contains local device address & type per link.
 */
typedef BT_DEVICE_ADDR DQ_LOCAL_DEVICE_T;

/**
 *  Currently, per peer device entity, a local device address is being used.
 *  However, instances where number of local address used or needed being less
 *  than number of peer's supported. Alternate design of having a separate local
 *  address was considered, but currently, for simplicity, this design of local
 *  device address per instance is chosen. Simplicity is mentioned because, when
 *  local addresses are maintained separately and may have one to many mapping,
 *  deletion (freeing), seraching, etc will be needed for local address as well.
 */
#ifdef BT_DUAL_MODE

typedef struct
{
    /* Possible values, BT_BR_EDR_LINK, BT_LE_LINK */
    DEVICE_LINK_TYPE     link_type;

    BT_DEVICE_ADDR       remote_bd_addr;

    DQ_LOCAL_DEVICE_T    local_bd_addr;

}DEVICE_QUEUE_T;

#else /* BT_DUAL_MODE */

typedef struct
{
    BT_DEVICE_ADDR       remote_bd_addr;

    DQ_LOCAL_DEVICE_T    local_bd_addr;

}DEVICE_QUEUE_T;

#endif /* BT_DUAL_MODE */

#ifdef BT_STORAGE
void dq_pstorage_cb (UCHAR id, UCHAR type, UCHAR action);
#ifdef STORAGE_RETENTION_SUPPORT
void dq_rstorage_cb (UCHAR id, UCHAR type, UCHAR action);
#endif /* STORAGE_RETENTION_SUPPORT */
#endif /* BT_STORAGE */

#endif /* _H_DEVICE_QUEUE_INTERNAL_ */


